
/**
 *
 * @author group_0217
 */
public class TestClass {
    // Test the "mkdir", "cd", "echo >", "echo >>", "cp" and "mv" commands.
    // Actually, our "ls", "pwd", "cat" commands also work. However,
    // these commands just print things, we find them hard to test. Hence,
    // we didn't wreite methods to test them, but we already tested if
    // the contents of Files, contents of Directories and current working
    // path eligible in the following test functions.

    // The file system.
    private static JShell J;
    // Our root Directory.
    private static Directory js;

    /**
     * Create a TestClass Object.
     */
    public TestClass() {
        J = new JShell();
        // Get the root Directory.
        js = (Directory) J.getJs().getDir().get("JShell");
    }

    /**
     * Test mkdir command.
     * @throws TestError if mkdir not good.
     */
    public void testMkdir() throws TestError {
        String[] commands = new String[4];
        commands[0] = "mkdir sammy";
        commands[1] = "mkdir simon";
        commands[2] = "mkdir sammy/wells";
        commands[3] = "mkdir simon/allia";

        for (int i = 0; i <= 3; i++) {
            // Run those commands.
            J.readCom(commands[i], J);
        }


        if (!js.ifContain("sammy") || !js.ifContain("simon")) {
            // sammy and simon should already be created.
            throw new TestError("mkdir not good!");
        }

        if (!(((Directory) js.getDir().get("sammy")).ifContain("wells"))) {
            // wells should already be created in sammy.
            throw new TestError("mkdir not good!");
        }

        if (!(((Directory) js.getDir().get("simon")).ifContain("allia"))) {
            // allia should already be created in simon.
            throw new TestError("mkdir not good!");
        }

        // Didn't throw an error, everything is good!
        System.out.println("mkdir is good!");
    }

    /**
     * test echo >> command.
     * @throws TestError if echo >> not good.
     */
    public void testEchoAppend() throws TestError {
        String[] commands = new String[5];

        commands[0] = "cd";
        commands[1] = "echo sammy is awesome >> a";
        commands[2] = "echo sammy is awesome >> a";
        commands[3] = "echo sammy is awesome >> sammy/b";
        commands[4] = "cd";

        for (int i = 0; i <= 4; i++) {
            // Run those commands.
            J.readCom(commands[i], J);
        }

        if (!js.ifContain("a")) {
            // a should already exist.
            throw new TestError("echo >> not good!");
        }
        File a = (File) js.getDir().get("a");
        if (!(a.ReturnContents().equals("sammy is awesomesammy is awesome"))) {
            // Check the contents of a.
            throw new TestError("echo >> not good!");
        }

        Directory sammy = (Directory) js.getDir().get("sammy");
        if (!sammy.ifContain("b")) {
            // b should be in sammy.
            throw new TestError("echo >> not good!");
        }
        File b = (File) sammy.getDir().get("b");
        if (!b.ReturnContents().equals("sammy is awesome")) {
            // Chech the contents of b.
            throw new TestError("echo >> not good!");
        }

        // Didn't throw an error, everything is good!
        System.out.println("echo >> is good!");
    }

    /**
     * Test echo > command.
     * @throws TestError if echo > not good.
     */
    public void testEchoOverwrite() throws TestError {
        String[] commands = new String[3];

        commands[0] = "cd";
        commands[1] = "echo sammy is awesome > a";
        commands[2] = "echo sammy is awesome > sammy/b";

        for (int i = 0; i <= 2; i++) {
            // Run those commands.
            J.readCom(commands[i], J);
        }

        if (!js.ifContain("a")) {
            // a should already be created.
            throw new TestError("echo > not good!");
        }
        File a = (File) js.getDir().get("a");
        if (!(a.ReturnContents().equals("sammy is awesome"))) {
            // Chech the contents of a.
            throw new TestError("echo > not good!");
        }

        Directory sammy = (Directory) js.getDir().get("sammy");
        if (!sammy.ifContain("b")) {
            // b should already be in sammy.
            throw new TestError("echo > not good!");
        }
        File b = (File) sammy.getDir().get("b");
        if (!b.ReturnContents().equals("sammy is awesome")) {
            // Check the contents of b.
            throw new TestError("echo > not good!");
        }

        J.readCom("echo sammy is always awesome > a", J);
        if (!(a.ReturnContents().equals("sammy is always awesome"))) {
            // check the contents of a.
            throw new TestError("echo > not good!");
        }

        J.readCom("cd", J);
        // Didn't throw an error, everything is good!
        System.out.println("echo > is good!");
    }

    /**
     * check if cd command is correct
     * @throws TestError
     */
    public void testCd() throws TestError {
        // test of cd command
        J.readCom("cd sammy", J);
        if (!J.getCurLocation().equals("JShell/sammy")) {
            throw new TestError("cd not good!");
        }

        J.readCom("cd ../simon/allia", J);
        if (!J.getCurLocation().equals("JShell/simon/allia")) {
            throw new TestError("cd not good!");
        }

        J.readCom("cd .", J);
        if (!J.getCurLocation().equals("JShell/simon/allia")) {
            throw new TestError("cd not good!");
        }

        J.readCom("cd JShell/simon", J);
        if (!J.getCurLocation().equals("JShell/simon")) {
            throw new TestError("cd not good!");
        }

        J.readCom("cd", J);
        if (!J.getCurLocation().equals("JShell")) {
            throw new TestError("cd not good!");
        }

        // Didn't throw an error, everything is good!
        System.out.println("cd is good!");
    }

    /**
     * check if mv command is correct
     * @throws TestError
     */
    public void testMv() throws TestError {
        J.readCom("mkdir JShell/simon/allia/dir1", J);
        J.readCom("mkdir JShell/simon/allia/dir1/dir2", J);
        J.readCom("cd JShell/simon/allia", J);
        J.readCom("mv dir1 JShell", J);
        //test dir1 mv to JShell, JShell/simon/allia do not have dir1 inside
        if (((Directory) ((Directory) js.getDir().get("simon")).getDir().get("allia")).ifContain("dir1")) {
            throw new TestError("mv not good!");
        }
        J.readCom("cd JShell/dir1/dir2", J);
        if (!J.getCurLocation().equals("JShell/dir1/dir2")) {
            throw new TestError("mv not good!");
        }
        J.readCom("cd", J);
        //test if file mv is correct
        J.readCom("echo codes > child", J);
        J.readCom("mv child JShell/simon", J);
        if (!((Directory) js.getDir().get("simon")).ifContain("child")) {
            throw new TestError("mv not good!");
        }
        if (js.ifContain("child")) {
            throw new TestError("mv not good!");
        }
        J.readCom("cd", J);
        // Didn't throw an error, everything is good!
        System.out.println("mv is good!");
    }

    /**
     * check if cp command is correct
     * @throws TestError
     */
    public void testCp() throws TestError {
        J.readCom("cp dir1 JShell/simon/allia", J);
        //check if dir copied to JShell/simon/allia
        J.readCom("cd JShell/simon/allia/dir1/dir2", J);
        if (!J.getCurLocation().equals("JShell/simon/allia/dir1/dir2")) {
            throw new TestError("cp not good!");
        }
        J.readCom("cd JShell/dir1/dir2", J);
        if (!J.getCurLocation().equals("JShell/dir1/dir2")) {
            throw new TestError("cp not good!");
        }
        J.readCom("mkdir dir3", J);
        //check if dir1 and JShell/simon/allia/dir1 are two distinguished object
        Directory allia = ((Directory) ((Directory) js.getDir().get("simon")).getDir().get("allia"));
        if (((Directory) ((Directory) allia.getDir().get("dir1")).getDir().get("dir2")).ifContain("dir3")) {
            throw new TestError("mv not good!");
        }
        J.readCom("cd", J);
        //check if file object copy is correct
        J.readCom("echo codf > child1", J);
        J.readCom("cp child1 child2", J);
        if (!(js.ifContain("child1") && js.ifContain("child2"))) {
            throw new TestError("cp not good!");
        }
        J.readCom("echo codfcodf > child1", J);
        if (!(((File) js.getDir().get("child1")).ReturnContents().equals("codfcodf")
                && ((File) js.getDir().get("child2")).ReturnContents().equals("codf"))) {
            throw new TestError("cp not good!");
        }
        J.readCom("cd", J);
        // Didn't throw an error, everything is good!
        System.out.println("cp is good!");
    }

    public static void main(String[] args) {
        try {
            TestClass tc = new TestClass();

            System.out.println("Test mkdir command:");
            tc.testMkdir();
            System.out.println('\n');

            System.out.println("Test echo >> command:");
            tc.testEchoAppend();
            System.out.println('\n');

            System.out.println("Test echo > command:");
            tc.testEchoOverwrite();
            System.out.println('\n');

            System.out.println("Test cd command:");
            tc.testCd();
            System.out.println('\n');

            System.out.println("Test mv command:");
            tc.testMv();
            System.out.println('\n');

            System.out.println("Test cp command:");
            tc.testCp();
            System.out.println('\n');

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }
}
